import tkinter as tk
from tkinter import messagebox
import random
import json
import os
from tkinter import simpledialog
from tkinter import Toplevel, Text, Scrollbar

class GuessNumberGame:
    def __init__(self, master):
        self.master = master
        master.title("猜数字游戏 v2.2")  # 更新版本号
        master.geometry("500x350")  # 调整窗口尺寸
        master.configure(bg="#ecf0f1")  # 设置背景颜色

        # 初始化游戏数据
        self.high_scores_file = "highscores.json"
        self.high_scores = self.load_highscores()
        self.target = random.randint(1, 100)
        self.remaining_attempts = 7
        self.win = 0
        self.lose = 0
        self.round = 1

        # 创建界面元素
        self.create_widgets()
        self.update_display()

    def load_highscores(self):
        """加载历史高分记录"""
        if os.path.exists(self.high_scores_file):
            try:
                with open(self.high_scores_file, 'r') as f:
                    data = json.load(f)
                    # 验证数据格式
                    if isinstance(data, list) and all(isinstance(item, dict) and "name" in item and "score" in item for item in data):
                        return data
            except:
                pass
        return []

    def create_widgets(self):
        """创建界面组件"""
        # 主容器
        main_frame = tk.Frame(self.master, padx=20, pady=15, bg="#ecf0f1")  # 设置背景颜色
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 游戏信息显示区
        self.stats_frame = tk.Frame(main_frame, bg="#ecf0f1")
        self.stats_frame.grid(row=0, column=0, sticky=tk.W)
        
        self.round_label = tk.Label(self.stats_frame, 
                                  font=('微软雅黑', 12, 'bold'),  # 加粗
                                  fg='#3498db', bg="#ecf0f1")  # 蓝色字体，背景色
        self.round_label.pack(anchor=tk.W)
        
        self.hint_label = tk.Label(self.stats_frame, 
                                 text="等待第一次猜测...",
                                 font=('微软雅黑', 11),
                                 fg='#2c3e50', bg="#ecf0f1")  # 深灰色字体，背景色
        self.hint_label.pack(anchor=tk.W, pady=5)

        # 添加“上次输入”标签
        self.last_input_label = tk.Label(self.stats_frame,
                                         text="上次输入：无",
                                         font=('微软雅黑', 9),
                                         fg='#7f8c8d', bg="#ecf0f1")  # 灰色字体，背景色
        self.last_input_label.pack(anchor=tk.W, pady=2)

        # 输入区域
        input_frame = tk.Frame(main_frame, bg="#ecf0f1")
        input_frame.grid(row=1, column=0, sticky=tk.W, pady=15)
        
        tk.Label(input_frame, text="输入数字：", 
                font=('微软雅黑', 11), bg="#ecf0f1").pack(side=tk.LEFT)
        self.entry = tk.Entry(input_frame, 
                            font=('Arial', 11), 
                            width=8)
        self.entry.pack(side=tk.LEFT, padx=5)
        self.entry.bind("<Return>", lambda e: self.submit_guess())
        self.entry.focus_set()
        
        tk.Button(input_frame, text="提交", 
                 command=self.submit_guess, 
                 width=6,
                 bg="#2ecc71",  # 绿色
                 fg="white",
                 activebackground="#27ae60",
                 relief=tk.FLAT,
                 font=('微软雅黑', 10)).pack(side=tk.LEFT)

        # 高分榜
        scores_frame = tk.LabelFrame(main_frame, 
                                   text="高分榜",
                                   font=('微软雅黑', 11),
                                   padx=10, pady=5,
                                   bg="#ecf0f1", fg="#2c3e50")  # 设置背景和字体颜色
        scores_frame.grid(row=0, column=1, rowspan=2, 
                        padx=15, sticky=tk.N)

        self.scores_list = tk.Listbox(scores_frame,
                                    height=8,
                                    width=20,
                                    font=('Consolas', 10),
                                    bg="#f0f0f0",  # 浅灰色
                                    borderwidth=0,
                                    highlightthickness=0)
        self.scores_list.pack()

        # 操作按钮
        btn_frame = tk.Frame(main_frame, bg="#ecf0f1")
        btn_frame.grid(row=2, column=0, columnspan=2, pady=20)
        tk.Button(btn_frame, text="帮助", 
                 command=self.show_help, 
                 width=8,
                 bg="#3498db",  # 蓝色
                 fg="white",
                 activebackground="#2980b9",
                 relief=tk.FLAT,
                 font=('微软雅黑', 10)).pack(side=tk.LEFT, padx=8)
        tk.Button(btn_frame, text="退出", 
                 command=self.on_exit,
                 width=8,
                 bg="#e74c3c",  # 红色
                 fg="white",
                 activebackground="#c0392b",
                 relief=tk.FLAT,
                 font=('微软雅黑', 10)).pack(side=tk.LEFT, padx=8)

        # 作者信息
        tk.Label(main_frame,
               text="开发者：@飙志 | BiaoZyx@outlook.com",
               font=('微软雅黑', 9),
               fg='#999999', bg="#ecf0f1").grid(row=3, column=0, columnspan=2, pady=5)

    def submit_guess(self):
        """处理猜测逻辑"""
        try:
            guess = int(self.entry.get())
            # 更新“上次输入”标签
            self.last_input_label.config(text=f"上次输入：{guess}")
            self.remaining_attempts -= 1

            if guess < 1 or guess > 100:
                messagebox.showerror("错误", "请输入1-100之间的数字！")
                return

            # 更新提示信息
            if guess < self.target:
                hint = "小了"
                hint_color = "#e67e22"  # 橙色
            elif guess > self.target:
                hint = "大了" 
                hint_color = "#e67e22"  # 橙色
            else:
                hint = "猜对了！"
                hint_color = "#2ecc71"  # 绿色

            # 实时显示提示
            self.hint_label.config(
                text=f"提示：{hint}（剩余次数：{self.remaining_attempts}）",
                fg=hint_color
            )

            # 处理正确猜测
            if guess == self.target:
                used_attempts = 7 - self.remaining_attempts
                # 获取玩家昵称
                player_name = simpledialog.askstring("游戏成功", "恭喜！请输入你的昵称：", parent=self.master)
                if not player_name:
                    player_name = "无名玩家"
                # 保存玩家昵称和分数
                self.high_scores.append({"name": player_name, "score": used_attempts})
                messagebox.showinfo("游戏成功",
                                    f"恭喜 {player_name}！正确答案：{self.target}\n"
                                    f"使用次数：{used_attempts}")
                self.win += 1
                self.new_round()
            elif self.remaining_attempts <= 0:
                messagebox.showinfo("游戏失败",
                                    f"游戏结束！正确答案：{self.target}")
                self.lose += 1
                self.new_round()

            self.update_display()
            self.entry.delete(0, tk.END)

        except ValueError:
            messagebox.showerror("输入错误", "请输入有效数字！")
            self.entry.delete(0, tk.END)

    def update_display(self):
        """更新界面显示"""
        self.round_label.config(
            text=f"第{self.round}轮 | 剩余次数：{self.remaining_attempts}\n"
                 f"胜利：{self.win}  失败：{self.lose}"
        )
        self.update_highscores()

    def update_highscores(self):
        """更新高分榜"""
        self.scores_list.delete(0, tk.END)
        # 过滤无效数据并排序
        valid_scores = [score for score in self.high_scores if isinstance(score, dict) and "name" in score and "score" in score]
        sorted_scores = sorted(valid_scores, key=lambda x: x["score"])
        for idx, score_data in enumerate(sorted_scores[:10], 1):
            self.scores_list.insert(tk.END, f"{idx}. {score_data['name']} - {score_data['score']}次")

    def new_round(self):
        """开始新回合"""
        self.target = random.randint(1, 100)
        self.remaining_attempts = 7
        self.round += 1
        self.save_highscores()
        self.hint_label.config(text="新回合开始！", fg="#2c3e50")
        self.update_display()

    def save_highscores(self):
        """保存高分记录"""
        # 过滤无效数据
        valid_scores = [score for score in self.high_scores if isinstance(score, dict) and "name" in score and "score" in score]
        with open(self.high_scores_file, 'w') as f:
            json.dump(sorted(valid_scores, key=lambda x: x["score"])[:10], f)

    def show_help(self):
        """显示帮助信息"""
        help_text = """【游戏规则】
1. 系统会随机生成1-100之间的整数
2. 每轮游戏有7次猜测机会
3. 输入数字后系统会提示"大了"或"小了"
4. 猜中数字即获胜，7次未中则失败

【游戏技巧】
1. 首猜建议选中间数（如50）
2. 根据提示缩小范围（如50大了下次猜25）
3. 注意剩余次数，合理分配猜测范围
4. 可以使用二分法快速逼近答案

【游戏系统】
1. 系统采用json格式保存高分榜数据，每次保存前十个高分。
2. 游戏结束前会提示输入昵称，用于保存高分榜。
3. 游戏结束后会自动保存高分榜数据。
4. 游戏开始时会自动加载历史高分榜数据。

【游戏开发】
1. 作者：@飙志
2. 邮箱：BiaoZyx@outlook.com
3. 这个游戏的开发有AI参与，欢迎提出建议和意见。

提示：输入非数字内容会导致错误提示
"""

        # 创建一个新的顶级窗口
        help_window = Toplevel(self.master)
        help_window.title("游戏帮助")
        help_window.geometry("500x400")  # 设置窗口大小

        # 创建滚动条
        scrollbar = Scrollbar(help_window)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 创建文本区域
        text_area = Text(help_window, wrap=tk.WORD, yscrollcommand=scrollbar.set, padx=10, pady=10)
        text_area.insert(tk.INSERT, help_text)
        text_area.config(state=tk.DISABLED)  # 设置为只读
        text_area.pack(fill=tk.BOTH, expand=True)

        # 将滚动条与文本区域绑定
        scrollbar.config(command=text_area.yview)

    def on_exit(self):
        """退出游戏"""
        self.save_highscores()
        self.master.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    game = GuessNumberGame(root)
    root.mainloop()